using System;
using System.Collections;
using System.IO;
using System.Text;

namespace Slaks.Web.Parser
{
  public class HtmlStructure
  {
		public static readonly string CloseTagRepresentationNothing = "";
    protected ArrayList m_htmlStructure = null;
    protected ArrayList m_anchors = null;
		protected StringBuilder m_textArray = null;
    protected string m_color = String.Empty;
    protected string m_tagName;
		protected string m_closeTagRepresentation;
    protected int m_depthCounter;
    protected static int m_totalCounter = 0;
		protected int m_thisCounter;

    public HtmlStructure(string tagName, string closeTagRepresentation, int depthCounter) 
		{
			m_tagName = tagName;
			m_closeTagRepresentation = closeTagRepresentation;
      m_depthCounter = depthCounter;
      m_thisCounter = ++m_totalCounter;
			m_textArray = new StringBuilder();
		}

		/// <summary>
		/// Get or set structures whithin this structure
		/// </summary>
    public IList Structure
    {
      get 
      {
        if (m_htmlStructure == null) m_htmlStructure = new ArrayList();
        return m_htmlStructure;
      }
    }
    public string Color { get { return m_color; } set { m_color = value; } }

		/// <summary>
		/// Get or set anchors (hrefs)
		/// </summary>
    public IList Anchors
    {
      get 
      {
        if (m_anchors == null) m_anchors = new ArrayList();
        return m_anchors;
      }
    }

		/// <summary>
		/// Get the representation of the close tag 
		/// Example: for form structure, the close tag is "/form"
		/// </summary>
		public string CloseTagRepresentation
		{
			get { return m_closeTagRepresentation; }
		}

		/// <summary>
		/// Get the name of this structure
		/// </summary>
		public string TagName { get { return m_tagName; } }

		/// <summary>
		/// Get Depth counter of this structure
		/// </summary>
    public int DepthCounter { get { return m_depthCounter; } }

		/// <summary>
		/// Get Static counter of structures
		/// </summary>
    public static int TotalCounter { get { return m_totalCounter; } }

		/// <summary>
		/// Reset the static counter of the structures
		/// </summary>
		public static void ResetCounter() { m_totalCounter = 0; }

		/// <summary>
		/// Get Structure number
		/// </summary>
		public int ThisCounter { get { return m_thisCounter; } }

		public string TextArray
		{
			get 
			{
				return m_textArray.ToString();
			}
		}

		public void AddText(string text)
		{
			m_textArray.Append(text);
			m_textArray.Append(Environment.NewLine);
		}

		protected HtmlStructure FindStructure(HtmlStructure structure,int index)
		{
			if (structure.ThisCounter == index) return this;
			if (structure.ThisCounter > index) return null;

			IList structureList = structure.Structure;

			for (int i=0;i<structureList.Count;i++)
			{
				if (((HtmlStructure)structureList[i]).ThisCounter < index)
				{
					HtmlStructure foundStructure = FindStructure((HtmlStructure)structureList[i],index);
					if (foundStructure != null) return foundStructure;
				}
				else if (((HtmlStructure)structureList[i]).ThisCounter == index) return ((HtmlStructure)structureList[i]);
				else return null;
			}
			return null;
		}

		public HtmlStructure GetStructureByIndex(int index)
		{
      return FindStructure(this,index);
		}


    /// <summary>
    /// Get the number of direct substructures of current structure
    /// </summary>
    /// <returns></returns>
    public int GetNumberOfSubStructures()
    {
      return m_htmlStructure.Count;
    }

    /// <summary>
    /// Get number of links contained in current structure
    /// </summary>
    /// <returns></returns>
    public int GetNumberOfLinks()
    {
			if (m_anchors == null) return 0;
      return m_anchors.Count;
    }

    /// <summary>
    /// Check whether the structure contains text
    /// </summary>
    /// <returns></returns>
    public bool IsTextExists()
    {
      return (m_textArray.Length != 0);
    }


		public void TextArrayString(TextWriter writer)
		{
      if (writer == null) return;

			if (m_textArray == null) return;

      writer.WriteLine(this.TextArray);
		}
  }
}